Skip to content

feat: support generated (computed) columns via the generated tag#230

Open
h2zi wants to merge 1 commit into
go-gorm:masterfrom
h2zi:feat/generated-columns
Open

feat: support generated (computed) columns via the generated tag#230
h2zi wants to merge 1 commit into
go-gorm:masterfrom
h2zi:feat/generated-columns

Conversation

@h2zi

@h2zi h2zi commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

What this adds

Support for SQLite STORED generated columns through the generated struct tag, keeping the generation expression separate from the column type. Part of rounding out generated-column support across the GORM drivers (see go-gorm/postgres#345 for the PostgreSQL side, which also covers identity columns). Relates to go-gorm/gorm#7191.

type Product struct {
    ID       uint    `gorm:"primaryKey"`
    Price    float64
    Quantity int
    Total    float64 `gorm:"->;generated:price * quantity"` // real GENERATED ALWAYS AS (price * quantity) STORED
}
  • The generated value is taken verbatim as the expression of a STORED generated column (SQLite 3.31+). Commas inside the expression are preserved, so generated:coalesce(a, b) works.
  • Combine with -> so GORM treats the column as read-only (SQLite forbids writing generated columns).
  • The identity keyword is reserved for identity columns; SQLite has no SQL-standard identity, so generated:identity is left to the existing AUTOINCREMENT handling rather than being mistaken for an expression.

Implementation

DataTypeOf appends the GENERATED ALWAYS AS (...) STORED clause when a computed expression is present; the base column type is computed exactly as before.

Tests & verification

  • Unit test TestDataTypeOfGeneratedColumn covers the computed clause, comma-safe expressions, and the reserved identity keyword.
  • Verified end-to-end against real SQLite: CREATE TABLE emits "total" real GENERATED ALWAYS AS (price * quantity) STORED, INSERT omits the generated column, the read-back value is correct, and repeated AutoMigrate runs are idempotent.
CREATE TABLE `products` (`id` integer PRIMARY KEY AUTOINCREMENT,`name` text,`price` real,
  `quantity` integer,`total` real GENERATED ALWAYS AS (price * quantity) STORED)

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds SQLite support in the GORM SQLite dialector for STORED generated (computed) columns via a generated struct tag by appending the GENERATED ALWAYS AS (...) STORED clause to the column’s SQL type during migration.

Changes:

  • Extend Dialector.DataTypeOf to emit ... GENERATED ALWAYS AS (<expr>) STORED when a GENERATED tag setting is present.
  • Add parsing helpers to treat identity (optionally with always / by default) as a reserved keyword (i.e., not a computed expression).
  • Add unit test coverage for the generated-column datatype rendering behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
sqlite.go Adds generated-column handling in DataTypeOf and helpers to interpret the generated tag and reserve identity.
generated_test.go Adds unit tests validating generated-column datatype rendering (including comma-containing expressions and reserved identity).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread generated_test.go
Render SQLite STORED generated columns from a `generated` tag, keeping the
generation expression separate from the column type:

  Total float64 `gorm:"->;generated:price * quantity"`
  // -> "total" real GENERATED ALWAYS AS (price * quantity) STORED

The expression is taken verbatim, so commas inside it (e.g. coalesce(a, b))
are preserved; combine with the `->` read-only permission. The `identity`
keyword is reserved for identity columns and is rendered through SQLite's
native AUTOINCREMENT, so it is not treated as a computed-column expression.

Relates to go-gorm/gorm#7191

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@h2zi h2zi force-pushed the feat/generated-columns branch from 94d4368 to 13d7cf0 Compare June 28, 2026 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants